﻿/*
 *  This file is part of SXAPI.
 *
 *  SXAPI is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Lesser General Public License as published by
 *  the Free Software Foundation, version 3 of the License.

 *  SXAPI is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Lesser General Public License for more details.
 *  
 *  You should have received a copy of the GNU Lesser General Public License
 *  along with SXAPI.  If not, see <http://www.gnu.org/licenses/>.
 */

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;

namespace StackExchangeApi
{
    /// <summary>
    /// An companion class to User that eagerly fetches
    /// all of its properties.
    /// 
    /// To use, obtain an User instance and cast it (implicitly
    /// or otherwise) to an EagerUser.
    /// </summary>
    public sealed class EagerUser
    {
        /// <summary>
        /// Implicitly cast a User to an EagerUser.
        /// 
        /// Doing so causes all the Properties on the User
        /// to be fetched.
        /// </summary>
        /// <param name="user">The User to eagerly load.</param>
        /// <returns>An EagerUser with all its properties fetched.</returns>
        public static implicit operator EagerUser(User user)
        {
            return new EagerUser(user);
        }

        /// <summary>
        /// Site this user is a member of
        /// </summary>
        public StackExchangeSite Site { get; internal set; }

        /// <summary>
        /// Id of this User
        /// </summary>
        public long Id
        {
            get;
            internal set;
        }

        /// <summary>
        /// The Badges earned by this User.
        /// 
        /// If the User has earned a particular Badge
        /// more than once, it will be including multiple times
        /// accordingly.
        /// </summary>
        public ReadOnlyCollection<Badge> Badges
        {
            get;
            internal set;
        }

        /// <summary>
        /// The recent activity of this User.
        /// 
        /// Contains a list of Answers, Questions, and Comments.
        /// 
        /// Size is determined by the "Trilogy Site".
        /// </summary>
        public ReadOnlyCollection<Post> RecentActivity
        {
            get;
            internal set;
        }

        /// <summary>
        /// ReputationGraph for this User.
        /// Allows access to all reputation modifying
        /// events in this User's history based on the time
        /// they occured.
        /// </summary>
        public ReputationGraph ReputationGraph
        {
            get;
            internal set;
        }

        /// <summary>
        /// Name of this user
        /// </summary>
        public String Name
        {
            get;
            internal set;
        }

        /// <summary>
        /// List of answers this User has posted
        /// </summary>
        public ReadOnlyCollection<Answer> Answers
        {
            get;
            internal set;
        }

        /// <summary>
        /// List of questions this User has asked
        /// </summary>
        public ReadOnlyCollection<Question> Questions
        {
            get;
            internal set;
        }

        /// <summary>
        /// List of questions this User has Favorited
        /// </summary>
        public ReadOnlyCollection<Question> FavoriteQuestions
        {
            get;
            internal set;
        }

        /// <summary>
        /// The Uri to pull a User's gravatar from.
        /// </summary>
        public Uri Gravatar
        {
            get;
            internal set;
        }

        /// <summary>
        /// Reputation this user has
        /// </summary>
        public long Reputation
        {
            get;
            internal set;
        }

        /// <summary>
        /// The number of gold badges this User has
        /// </summary>
        public long GoldBadgeCount
        {
            get;
            internal set;
        }

        /// <summary>
        /// The number of silver badges this User has
        /// </summary>
        public long SilverBadgeCount
        {
            get;
            internal set;
        }

        /// <summary>
        /// The number of bronze badges this User has.
        /// </summary>
        public long BronzeBadgeCount
        {
            get;
            internal set;
        }

        /// <summary>
        /// Construct a new EagerUser.
        /// 
        /// Uses reflection to iterate over all properties on
        /// ans and set its own properties accordingly.
        /// 
        /// This guarantees that all would-be-delayed loading
        /// is infact run immediately.
        /// </summary>
        /// <param name="user">The User in question</param>
        internal EagerUser(User user)
        {
            Utils.EagerlyLoad(user, this, typeof(User), typeof(EagerUser));
        }
    }
}
